package engine.operators.natural;

import its.util.RandomFactory;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import engine.Operator;
import engine.Population;
import engine.individuals.ProgramedTrafficNetIndividual;
import engine.individuals.TrafficNetIndividual;

/**
 * Performs mutation of the individual by randomly negating one bit with some
 * probability.
 */
public class NaturalConstrainedMutation<T extends TrafficNetIndividual<?>>
		implements Operator<T> {

	private final double mutationProbability;

	/**
	 * Returns a mutator, which modifies each bit of the
	 * {@link ProgramedTrafficNetIndividual} negated with some probability.
	 * 
	 * @param mutationProbability
	 *          Probability of the mutation of each individual.
	 */
	public NaturalConstrainedMutation(double mutationProbability) {
		this.mutationProbability = mutationProbability;
	}

	/** {@inheritDoc} */
	public Population<T> apply(Population<T> population) {
		Iterator<T> iterator = population.getIndividuals().iterator();
		List<T> output = new ArrayList<T>();

		while (iterator.hasNext()) {
			T ind = iterator.next();

			if (RandomFactory.getNextDouble() < mutationProbability && ind.size() > 1) {

				ind.mutate();
			}

			output.add(ind);
		}
		return population;
	}
}
